//-----------------------------------------------------------------------------
//
// @file	Utils.h
// @brief	Utils include files, variables and classes
// @author	Vinod Melapudi
// @date	20Feb2010
//
//-----------------------------------------------------------------------------

#ifndef _UTILS_H
#define _UTILS_H

#include "stdio.h"
#include "math.h"

#include <vector>
#include <string>
#include <algorithm>
#include <windows.h>
#include <windowsx.h>
#include <stdarg.h>



// Abort
inline void errlog(const char * s, ...)
{
	va_list args;
	va_start(args, s);
	vfprintf(stderr, s, args);
	fprintf(stderr, "\n");
	va_end(args);
}

//-----------------------------------------------------------------------------

// TYPEDEF

typedef unsigned int		uint;

//-----------------------------------------------------------------------------

// MATH DEFINES

// Range of real numbers
#define SMALLNUMBER	1.0e-10 
#define HUGENUMBER	1.0e10 

// Miscellaneous Scalar Math 
#define abs(x)			(((x) < 0) ? (-(x)) : (x)) 
#define sqr(x)			((x) * (x)) 
//#define min(x1,x2)	((x1)<(x2)?(x1):(x2)) 
//#define max(x1,x2)	((x1)>(x2)?(x1):(x2)) 
#define round(x, p)		(((int)((x)*pow((float)10,(int)p)+((x)<0?-0.5:0.5)))/pow((float)10,(int)p)) 
#define sign(x)			((x)>=0? 1: -1) 
#define swap(x1, x2)	{int tmp=x1; x1=x2; x2=tmp} 
#define applysign(x, y)	((y) >= 0? abs(x): -abs(x))
#define clamp(x,v1,v2)	min( max( x, v1 ), v2 )

// Angle Conversions & Constants
#ifndef PI 
#define PI 3.1415926535897 
#endif 
 
#define RAD2DEG (180/PI) 
#define DEG2RAD (PI/180) 
 
#define DegToRad(x) ((x)*DEG2RAD) 
#define RadToDeg(x) ((x)*RAD2DEG) 

//-----------------------------------------------------------------------------

// ENUMS

enum AXIS
{
	AXIS_X,
	AXIS_Y,
	AXIS_Z,
	AXIS_NONE
};

//-----------------------------------------------------------------------------

// LERP

template<class T>
T Lerp( T v1, T v2, float t )
{
	return v1 + (v2 - v1) * t;
}

template<class T>
float Param( T v1, T v2, T v )
{
	return (float)(v - v1) / (float)(v2 - v1);
}


typedef enum 
{
	INTERP_LINEAR,
	INTERP_QUADRATIC,
	INTERP_CUBIC,		// Blending end points with Hermite basis
	INTERP_CARDINAL,	// Blending with Hermite basis using Catmul-Rom tangents built from end points
	INTERP_HERMITE,		// Tangents provided
	INTERP_BEZIER,		// Control pts provided

	INTERP_MAX
} INTERP_TYPE;


static std::string GetInterpTypeName( INTERP_TYPE type )
{
	// Hud Text
	switch( type )
	{
	case INTERP_LINEAR:		return "LINEAR";	break;
	case INTERP_QUADRATIC:	return "QUADRATIC";	break;
	case INTERP_CUBIC:		return "CUBIC";		break;
	case INTERP_CARDINAL:	return "CARDINAL";	break;
	case INTERP_HERMITE:	return "HERMITE";	break;
	case INTERP_BEZIER:		return "BEZIER";	break;
	};

	return "UNHANDLED";
}

//-----------------------------------------------------------------------------

// STRING HELPER

std::vector<std::string> GetStringTokens( const char* str_, const char* delimiter );


//-----------------------------------------------------------------------------

static int NearestPowerOf2( int x ) 
{
	--x;    
	x |= x >> 1;
	x |= x >> 2;    
	x |= x >> 4;    
	x |= x >> 8;    
	x |= x >> 16;    
	int y = ++x;
	return y;
}

static bool IsPowerOf2( int x )
{
	return (x & x-1) == 0;
}


static int NumberOf1Bit( int x )
{
	int n = 0;
	while ( x )
	{
		x = x & x-1;
		n++;
	}
	return n;
}

#endif
